import os
from enum import Enum

from bidict import bidict
from easydict import EasyDict

__all__ = [
    "METRICS_CATEGORY", "INDEX_STATICAL_FORMATS",  # metrics value
    "INDEX_METRICS_FUNDAMENTAL", "INDEX_METRICS_FINANCE", "INDUSTRY_CATEGORY", "STOCK_METRICS",  # metrics value
    "A_INDEX_DICT", "STOCK_CODE_DICT",  # some invest codes
    "ASSET_CLASS", "ASSET_NAME_DICT",   # asset allocation
]


METRICS_CATEGORY = EasyDict({'fundamental': 'fundamental', 'finance': 'fs', 'sample': 'constituents'})


# index
INDEX_STATICAL_FORMATS = ["avgv", "cv", "cvpos", "maxpv", "maxv", "minv", "q2v", "q5v", "q8v"]
"""
Attributes:
    - fundamental: dyr股息率(dividend yield rate) tv成交(turnover volume) ta成交额(turnover account) sp股价(stock price) 
    mc市值(market capitalization) cp 现价(current price) fb融资余额(funding balance) sb融券余额(short selling balance)
    request: ["pe_ttm", "pe_ttm_pos10", "pb", "pb_pos10", "dyr", "cp", "tv", "fc_rights", "mc"] 
    note: dyr/pe/pb/ps 支持metricsType; pe/pb/ps 支持granularity; 其余不支持 \n
    - finance: fcf 自由现金流(free cash flow), np_s_r净利润率(net profit-sell-rate) \n
    - sample: stockCode 样本股票代码
"""
_INDEX_METRICS_DICT: EasyDict = EasyDict()
_INDEX_METRICS_DICT.fundamental = {
    "metricsType": {"market_cap_weighted": "mcw", "equally_weighted": "ew", "average": "avg", "median": "median"},
    "granularity": {"all": "fs", "y20": "y20", "y10": "y10", "y5": "y5", "y3": "y3"},
    "metricsName": {"pe": "pe_ttm", "pb": "pb", "ps": "ps_ttm", "dyr": "dyr", "turnover_volume": "tv",
                    "turnover_account": "ta", "current_price": "cp", "current_price_change": "cpc", "market_cap": "mc",
                    "funding_balance": "fb", "short_balance": "sb"},
    "format": "metricsName.granularity.metricsType"
}
_INDEX_METRICS_DICT.finance = {
    "granularity": {"year": "y", "quarter": "q", "half_year": "hy"},
    "expressionCalculateType": {"cumulative": "t", "cumulative_y2y": "t_y2y", "cumulative_c2c": "t_c2c",
                                "current": "c", "current_y2y": "c_y2y", "current_c2c": "c_c2c",
                                "trailing_twelve_months": "ttm", "trailing_twelve_months_y2y": "ttm_y2y",
                                "trailing_twelve_months_c2c": "ttm_c2c"},
    "tableName": {"profit_sheet": "ps", "balance_sheet": "bs", "cash_flow_sheet": "cfs", "f_index": "m"},
    "fieldName": {"profit_sheet": {"operate_income": "ps.oi", "net_profit": "ps.np", "net_profit_rate": "ps.np_s_r"},
                  "balance_sheet": {"total_assets": "bs.ta", "total_liabilities": "bs.tl", "circulation_share_capital": "bs.csc"},
                  "cash_flow_sheet": {"net_profit": "cfs.np"},
                  "f_index": {"roe": "m.roe", "roa": "m.roa", "net_profit_rate": "m.np_s_r", "free_current_flow": "m.fcf"}
                  },
    "format": "granularity.tableName.fieldName.expressionCalculateType",
}

_INDEX_METRICS_DICT.SAMPLE = "stockCode"


class INDEX_METRICS_FUNDAMENTAL(Enum):
    PE = ".".join([_INDEX_METRICS_DICT.fundamental.metricsName['pe'], _INDEX_METRICS_DICT.fundamental.granularity["y20"],
                   _INDEX_METRICS_DICT.fundamental.metricsType['market_cap_weighted']])
    PB = ".".join([_INDEX_METRICS_DICT.fundamental.metricsName['pb'], _INDEX_METRICS_DICT.fundamental.granularity["y20"],
                   _INDEX_METRICS_DICT.fundamental.metricsType['market_cap_weighted']])
    MC = _INDEX_METRICS_DICT.fundamental.metricsName['market_cap']
    CP = _INDEX_METRICS_DICT.fundamental.metricsName['current_price']
    DYR = ".".join(
        [_INDEX_METRICS_DICT.fundamental.metricsName['dyr'], _INDEX_METRICS_DICT.fundamental.metricsType['market_cap_weighted']])
    REQUEST = [PE, PB, MC, CP, DYR]
    NAME = "fundamental_PE_PB_MC_CP_DYR"
    PE_POS = PE + ":cvpos"
    PB_POS = PB + ":cvpos"


class INDEX_METRICS_FINANCE(Enum):
    ROE = ".".join(
        [_INDEX_METRICS_DICT.finance.granularity['quarter'], _INDEX_METRICS_DICT.finance.fieldName["f_index"]['roe'],
         _INDEX_METRICS_DICT.finance.expressionCalculateType['trailing_twelve_months']])
    FCF = ".".join(
        [_INDEX_METRICS_DICT.finance.granularity['quarter'], _INDEX_METRICS_DICT.finance.fieldName["f_index"]['free_current_flow'],
         _INDEX_METRICS_DICT.finance.expressionCalculateType['trailing_twelve_months']])
    NP_S_R = ".".join(
        [_INDEX_METRICS_DICT.finance.granularity['quarter'], _INDEX_METRICS_DICT.finance.fieldName["f_index"]['net_profit_rate'],
         _INDEX_METRICS_DICT.finance.expressionCalculateType['trailing_twelve_months']])
    TOTAL_ASSETS = ".".join(
        [_INDEX_METRICS_DICT.finance.granularity['quarter'], _INDEX_METRICS_DICT.finance.fieldName["balance_sheet"]['total_assets'],
         _INDEX_METRICS_DICT.finance.expressionCalculateType['cumulative']])
    TOTAL_LIABILITIES = ".".join(
        [_INDEX_METRICS_DICT.finance.granularity['quarter'], _INDEX_METRICS_DICT.finance.fieldName["balance_sheet"]['total_liabilities'],
         _INDEX_METRICS_DICT.finance.expressionCalculateType['cumulative']])
    REQUEST = [ROE, FCF, NP_S_R, TOTAL_ASSETS, TOTAL_LIABILITIES]
    NAME = "finance_ROE_FCF_NP_S_R_TOTAL_ASSETS_TOTAL_LIABILITIES"


# company
INDUSTRY_CATEGORY = EasyDict({'non_finance': "non_financial",
                              'bank': "bank",
                              'security': "security",  # 证券
                              'insurance': "insurance"})


class STOCK_METRICS(Enum):
    """
    fundamental: dyr股息率 tv成交 sp股价 mc市值 cp现价, 前复权fc_rights
    ["pe_ttm", "pe_ttm_pos10", "pb", "pb_pos10", "dyr", "sp", "tv", "fc_rights", "mc"]
    fundamental_insurance: 增加pev, pev_pos10
    finance: fcf 自由现金流, np_s_r净利润率
    """
    PE = "pe_ttm"
    PE_POS = "pe_ttm_pos10"
    PB = "pb"
    PB_POS = "pb_pos10"
    DYR = "dyr"
    Stoke_Price = "sp"
    Turnover_Volume = "tv"
    Frontal_Right = "lxr_fc_rights"
    Market_CAP = "mc"
    FUNDAMENTAL_REQUEST = [PE, PE_POS, PB, PB_POS, DYR, Stoke_Price, Turnover_Volume, Frontal_Right, Market_CAP]
    FUNDAMENTAL_NAME = "fundamental_"+"_".join(FUNDAMENTAL_REQUEST)
    PEV = "pev"
    PEV_POS = "pev_pos10"
    FUNDAMENTAL_INSURANCE_REQUEST = [PE, PE_POS, PB, PB_POS, DYR, Stoke_Price, Turnover_Volume, Frontal_Right,
                                     Market_CAP, PEV, PEV_POS]
    FUNDAMENTAL_INSURANCE_NAME = "fundamental_"+"_".join(FUNDAMENTAL_INSURANCE_REQUEST)
    FCF = "q.m.fcf.ttm"
    ROE = "q.m.roe.ttm"
    Net_Profit = "q.m.np_s_r.ttm"
    FINANCE_REQUEST = [FCF, ROE, Net_Profit]
    FINANCE_REQUEST_NAME = "finance_" + "_".join(FINANCE_REQUEST)


A_INDEX_DICT = bidict({
    "上证50": '000016',
    "沪深300": '000300',
    "中证500": '000905',
    "创业板指": '399006',
    "中证传媒": '399971',
    "中证红利": '000922',
    "中证消费": '000932',
    "中证养老": '399812',
    "全指医药": '000991',
    "全指金融": '000992',
    "中证环保": '000827',
    "全指信息": '000993',
    "沪深A股": '1000002'
})


STOCK_CODE_DICT = EasyDict({
    "GLDQ": {'name': "格力电器", 'code': '000651', 'industry_type': INDUSTRY_CATEGORY.non_finance},
    "ZGPA": {'name': "中国平安", 'code': '601318', 'industry_type': INDUSTRY_CATEGORY.insurance},
    "YYYL": {'name': "鱼跃医疗", 'code': '002223', 'industry_type': INDUSTRY_CATEGORY.non_finance},
    "DSDC": {'name': "德赛电池", 'code': '000049', 'industry_type': INDUSTRY_CATEGORY.non_finance},
    "HDYY": {'name': "华东医药", 'code': '000963', 'industry_type': INDUSTRY_CATEGORY.non_finance}
})


def c_asset_main_class(name, subclass, max_ratio):
    return {'name': name, 'subclass': subclass, 'max_ratio': max_ratio}


ASSET_CLASS = EasyDict()
ASSET_CLASS.A_share = c_asset_main_class('A股', {}, 0.8)
ASSET_CLASS.A_share.subclass.big_session = {'name': '大盘'}
ASSET_CLASS.A_share.subclass.middle_small_session = {'name': '中小盘'}
ASSET_CLASS.A_share.subclass.valued = {'name': '价值'}
ASSET_CLASS.A_share.subclass.industry = {'name': '行业'}

ASSET_CLASS.abroad_new = c_asset_main_class('海外新兴', {}, 0.4)
ASSET_CLASS.abroad_new.subclass.h_share = {'name': '香港'}
ASSET_CLASS.abroad_new.subclass.kweb = {'name': '海外互联'}

ASSET_CLASS.abroad_mature = c_asset_main_class('海外成熟', {}, 0.4)
ASSET_CLASS.abroad_mature.subclass.Europe = {'name': '欧洲'}
ASSET_CLASS.abroad_mature.subclass.America = {'name': '美国'}
ASSET_CLASS.abroad_mature.subclass.exchange = {'name': '外汇'}

ASSET_CLASS.commodities = c_asset_main_class('大宗商品', {}, 0.4)
ASSET_CLASS.commodities.subclass.gold = {'name': '黄金'}
ASSET_CLASS.commodities.subclass.oil = {'name': '原油'}

ASSET_CLASS.bond = c_asset_main_class('债券', {}, 0.4)
ASSET_CLASS.bond.subclass.national = {'name': '国内债券'}

ASSET_CLASS.cash = {'name': '现金'}

ASSET_NAME_DICT = {
    'A股': ASSET_CLASS.A_share,
    '大盘': ASSET_CLASS.A_share.subclass.big_session,
    '中小盘': ASSET_CLASS.A_share.subclass.middle_small_session,
    '价值': ASSET_CLASS.A_share.subclass.valued,
    '行业': ASSET_CLASS.A_share.subclass.industry,

    '海外新兴': ASSET_CLASS.abroad_new,
    '香港': ASSET_CLASS.abroad_new.subclass.h_share,
    '海外互联': ASSET_CLASS.abroad_new.subclass.kweb,

    '海外成熟': ASSET_CLASS.abroad_mature,
    '欧洲': ASSET_CLASS.abroad_mature.subclass.Europe,
    '美国': ASSET_CLASS.abroad_mature.subclass.America,
    '外汇': ASSET_CLASS.abroad_mature.subclass.exchange,

    '大宗商品': ASSET_CLASS.commodities,
    '黄金': ASSET_CLASS.commodities.subclass.gold,
    '原油': ASSET_CLASS.commodities.subclass.oil,

    '债券': ASSET_CLASS.bond,
    '国内债券': ASSET_CLASS.bond.subclass.national,

    '现金': ASSET_CLASS.cash
}
